// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.gameStates;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import zombie.core.Core;
import zombie.core.GameVersion;
import zombie.core.IndieFileLoader;
import zombie.core.Language;
import zombie.core.Translator;
import zombie.core.logger.ExceptionLogger;
import zombie.core.textures.Texture;
import zombie.core.textures.TextureID;
import zombie.core.znet.SteamWorkshop;
import zombie.debug.DebugLog;
import zombie.util.StringUtils;

public final class ChooseGameInfo {
    private static final HashMap<String, ChooseGameInfo.Map> Maps = new HashMap();
    private static final HashMap<String, ChooseGameInfo.Mod> Mods = new HashMap();
    private static final HashSet<String> MissingMods = new HashSet();
    private static final ArrayList<String> tempStrings = new ArrayList();

    private ChooseGameInfo() {
    }

    public static void Reset() {
        Maps.clear();
        Mods.clear();
        MissingMods.clear();
    }

    private static void readTitleDotTxt(ChooseGameInfo.Map map, String string1, Language language) throws IOException {
        String string0 = "media/lua/shared/Translate/" + language.toString() + "/" + string1 + "/title.txt";
        File file = new File(zombie.ZomboidFileSystem.instance.getString(string0));

        try {
            FileInputStream fileInputStream = new FileInputStream(file);

            try {
                InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, Charset.forName(language.charset()));

                try {
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                    try {
                        String string2 = bufferedReader.readLine();
                        string2 = StringUtils.stripBOM(string2);
                        if (!StringUtils.isNullOrWhitespace(string2)) {
                            map.title = string2.trim();
                        }
                    } catch (Throwable throwable0) {
                        try {
                            bufferedReader.close();
                        } catch (Throwable throwable1) {
                            throwable0.addSuppressed(throwable1);
                        }

                        throw throwable0;
                    }

                    bufferedReader.close();
                } catch (Throwable throwable2) {
                    try {
                        inputStreamReader.close();
                    } catch (Throwable throwable3) {
                        throwable2.addSuppressed(throwable3);
                    }

                    throw throwable2;
                }

                inputStreamReader.close();
            } catch (Throwable throwable4) {
                try {
                    fileInputStream.close();
                } catch (Throwable throwable5) {
                    throwable4.addSuppressed(throwable5);
                }

                throw throwable4;
            }

            fileInputStream.close();
        } catch (FileNotFoundException fileNotFoundException) {
        }
    }

    private static void readDescriptionDotTxt(ChooseGameInfo.Map map, String string1, Language language) throws IOException {
        String string0 = "media/lua/shared/Translate/" + language.toString() + "/" + string1 + "/description.txt";
        File file = new File(zombie.ZomboidFileSystem.instance.getString(string0));

        try {
            FileInputStream fileInputStream = new FileInputStream(file);

            try {
                InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, Charset.forName(language.charset()));

                try {
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                    try {
                        map.desc = "";
                        boolean _boolean = true;

                        String string2;
                        while ((string2 = bufferedReader.readLine()) != null) {
                            if (_boolean) {
                                string2 = StringUtils.stripBOM(string2);
                                _boolean = false;
                            }

                            map.desc = map.desc + string2;
                        }
                    } catch (Throwable throwable0) {
                        try {
                            bufferedReader.close();
                        } catch (Throwable throwable1) {
                            throwable0.addSuppressed(throwable1);
                        }

                        throw throwable0;
                    }

                    bufferedReader.close();
                } catch (Throwable throwable2) {
                    try {
                        inputStreamReader.close();
                    } catch (Throwable throwable3) {
                        throwable2.addSuppressed(throwable3);
                    }

                    throw throwable2;
                }

                inputStreamReader.close();
            } catch (Throwable throwable4) {
                try {
                    fileInputStream.close();
                } catch (Throwable throwable5) {
                    throwable4.addSuppressed(throwable5);
                }

                throw throwable4;
            }

            fileInputStream.close();
        } catch (FileNotFoundException fileNotFoundException) {
        }
    }

    public static ChooseGameInfo.Map getMapDetails(String dir) {
        if (Maps.containsKey(dir)) {
            return (ChooseGameInfo.Map)Maps.get(dir);
        } else {
            File file = new File(zombie.ZomboidFileSystem.instance.getString("media/maps/" + dir + "/map.info"));
            if (!file.exists()) {
                return null;
            } else {
                ChooseGameInfo.Map map = new ChooseGameInfo.Map();
                map.dir = new File(file.getParent()).getAbsolutePath();
                map.title = dir;
                map.lotsDir = new ArrayList();

                try {
                    FileReader fileReader = new FileReader(file.getAbsolutePath());
                    BufferedReader bufferedReader = new BufferedReader(fileReader);
                    String string = null;

                    try {
                        while ((string = bufferedReader.readLine()) != null) {
                            string = string.trim();
                            if (string.startsWith("title=")) {
                                map.title = string.replace("title=", "");
                            } else if (string.startsWith("lots=")) {
                                map.lotsDir.add(string.replace("lots=", "").trim());
                            } else if (string.startsWith("description=")) {
                                if (map.desc == null) {
                                    map.desc = "";
                                }

                                map.desc = map.desc + string.replace("description=", "");
                            } else if (string.startsWith("fixed2x=")) {
                                map.bFixed2x = Boolean.parseBoolean(string.replace("fixed2x=", "").trim());
                            }
                        }
                    } catch (IOException iOException) {
                        Logger.getLogger(ChooseGameInfo.class.getName()).log(Level.SEVERE, null, iOException);
                    }

                    bufferedReader.close();
                    map.thumb = Texture.getSharedTexture(map.dir + "/thumb.png");
                    ArrayList arrayList = new ArrayList();
                    Translator.addLanguageToList(Translator.getLanguage(), arrayList);
                    Translator.addLanguageToList(Translator.getDefaultLanguage(), arrayList);

                    for (int _int = arrayList.size() - 1; _int >= 0; _int--) {
                        Language language = (Language)arrayList.get(_int);
                        readTitleDotTxt(map, dir, language);
                        readDescriptionDotTxt(map, dir, language);
                    }
                } catch (Exception exception) {
                    ExceptionLogger.logException(exception);
                    return null;
                }

                Maps.put(dir, map);
                return map;
            }
        }
    }

    public static ChooseGameInfo.Mod getModDetails(String modId) {
        if (MissingMods.contains(modId)) {
            return null;
        } else if (Mods.containsKey(modId)) {
            return (ChooseGameInfo.Mod)Mods.get(modId);
        } else {
            String string = zombie.ZomboidFileSystem.instance.getModDir(modId);
            if (string == null) {
                ArrayList arrayList0 = tempStrings;
                zombie.ZomboidFileSystem.instance.getAllModFolders(arrayList0);
                ArrayList arrayList1 = new ArrayList();

                for (int int0 = 0; int0 < arrayList0.size(); int0++) {
                    File file = new File((String)arrayList0.get(int0), "mod.info");
                    arrayList1.clear();
                    ChooseGameInfo.Mod mod0 = zombie.ZomboidFileSystem.instance.searchForModInfo(file, modId, arrayList1);

                    for (int int1 = 0; int1 < arrayList1.size(); int1++) {
                        ChooseGameInfo.Mod mod1 = (ChooseGameInfo.Mod)arrayList1.get(int1);
                        Mods.putIfAbsent(mod1.getId(), mod1);
                    }

                    if (mod0 != null) {
                        return mod0;
                    }
                }
            }

            ChooseGameInfo.Mod mod2 = readModInfo(string);
            if (mod2 == null) {
                MissingMods.add(modId);
            }

            return mod2;
        }
    }

    public static ChooseGameInfo.Mod getAvailableModDetails(String modId) {
        ChooseGameInfo.Mod mod = getModDetails(modId);
        return mod != null && mod.isAvailable() ? mod : null;
    }

    public static ChooseGameInfo.Mod readModInfo(String modDir) {
        ChooseGameInfo.Mod mod0 = readModInfoAux(modDir);
        if (mod0 != null) {
            ChooseGameInfo.Mod mod1 = (ChooseGameInfo.Mod)Mods.get(mod0.getId());
            if (mod1 == null) {
                Mods.put(mod0.getId(), mod0);
            } else if (mod1 != mod0) {
                zombie.ZomboidFileSystem.instance.getAllModFolders(tempStrings);
                int int0 = tempStrings.indexOf(mod0.getDir());
                int int1 = tempStrings.indexOf(mod1.getDir());
                if (int0 < int1) {
                    Mods.put(mod0.getId(), mod0);
                }
            }
        }

        return mod0;
    }

    private static ChooseGameInfo.Mod readModInfoAux(String string0) {
        if (string0 != null) {
            ChooseGameInfo.Mod mod0 = zombie.ZomboidFileSystem.instance.getModInfoForDir(string0);
            if (mod0.bRead) {
                return mod0.bValid ? mod0 : null;
            }

            mod0.bRead = true;
            String string1 = string0 + File.separator + "mod.info";
            File file0 = new File(string1);
            if (!file0.exists()) {
                DebugLog.Mod.warn("can't find \"" + string1 + "\"");
                return null;
            }

            mod0.setId(file0.getParentFile().getName());

            try {
                InputStreamReader inputStreamReader = IndieFileLoader.getStreamReader(string1);

                ChooseGameInfo.Mod mod1;
                label286: {
                    Object object0;
                    label287: {
                        label288: {
                            Object object1;
                            label289: {
                                Object object2;
                                label290: {
                                    Object object3;
                                    label291: {
                                        try {
                                            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

                                            label264: {
                                                label263: {
                                                    label262: {
                                                        label261: {
                                                            label260: {
                                                                label259: {
                                                                    try {
                                                                        while (true) {
                                                                            String string2;
                                                                            if ((string2 = bufferedReader.readLine()) == null) {
                                                                                if (mod0.getUrl() == null) {
                                                                                    mod0.setUrl("");
                                                                                }
                                                                                break;
                                                                            }

                                                                            if (string2.contains("name=")) {
                                                                                mod0.name = string2.replace("name=", "");
                                                                            } else if (string2.contains("poster=")) {
                                                                                String string3 = string2.replace("poster=", "");
                                                                                if (!StringUtils.isNullOrWhitespace(string3)) {
                                                                                    mod0.posters.add(string0 + File.separator + string3);
                                                                                }
                                                                            } else if (string2.contains("description=")) {
                                                                                mod0.desc = mod0.desc + string2.replace("description=", "");
                                                                            } else if (string2.contains("require=")) {
                                                                                mod0.setRequire(
                                                                                    new ArrayList(Arrays.asList(string2.replace("require=", "").split(",")))
                                                                                );
                                                                            } else if (string2.contains("id=")) {
                                                                                mod0.setId(string2.replace("id=", ""));
                                                                            } else if (string2.contains("url=")) {
                                                                                mod0.setUrl(string2.replace("url=", ""));
                                                                            } else if (string2.contains("pack=")) {
                                                                                String string4 = string2.replace("pack=", "").trim();
                                                                                if (string4.isEmpty()) {
                                                                                    DebugLog.Mod.error("pack= line requires a file name");
                                                                                    object3 = null;
                                                                                    break label264;
                                                                                }

                                                                                int int0 = TextureID.bUseCompressionOption ? 4 : 0;
                                                                                int int1 = int0 | 64;
                                                                                int int2 = string4.indexOf("type=");
                                                                                if (int2 != -1) {
                                                                                    String string5 = string4.substring(int2 + "type=".length());
                                                                                    byte byte0 = -1;
                                                                                    switch (string5.hashCode()) {
                                                                                        case 3732:
                                                                                            if (string5.equals("ui")) {
                                                                                                byte0 = 0;
                                                                                            }
                                                                                        default:
                                                                                            switch (byte0) {
                                                                                                case 0:
                                                                                                    int1 = 2;
                                                                                                    break;
                                                                                                default:
                                                                                                    DebugLog.Mod.error("unknown pack type=" + string5);
                                                                                            }

                                                                                            int int3 = string4.indexOf(32);
                                                                                            string4 = string4.substring(0, int3).trim();
                                                                                    }
                                                                                }

                                                                                String string6 = string4;
                                                                                String string7 = "";
                                                                                if (string4.endsWith(".floor")) {
                                                                                    string6 = string4.substring(0, string4.lastIndexOf(46));
                                                                                    string7 = ".floor";
                                                                                    int1 &= -5;
                                                                                }

                                                                                int int4 = Core.getInstance().getOptionTexture2x() ? 2 : 1;
                                                                                if (Core.SafeModeForced) {
                                                                                    int4 = 1;
                                                                                }

                                                                                if (int4 == 2) {
                                                                                    File file1 = new File(
                                                                                        string0
                                                                                            + File.separator
                                                                                            + "media"
                                                                                            + File.separator
                                                                                            + "texturepacks"
                                                                                            + File.separator
                                                                                            + string6
                                                                                            + "2x"
                                                                                            + string7
                                                                                            + ".pack"
                                                                                    );
                                                                                    if (file1.isFile()) {
                                                                                        DebugLog.Mod.printf("2x version of %s.pack found.\n", string4);
                                                                                        string4 = string6 + "2x" + string7;
                                                                                    } else {
                                                                                        file1 = new File(
                                                                                            string0
                                                                                                + File.separator
                                                                                                + "media"
                                                                                                + File.separator
                                                                                                + "texturepacks"
                                                                                                + File.separator
                                                                                                + string4
                                                                                                + "2x.pack"
                                                                                        );
                                                                                        if (file1.isFile()) {
                                                                                            DebugLog.Mod.printf("2x version of %s.pack found.\n", string4);
                                                                                            string4 = string4 + "2x";
                                                                                        } else {
                                                                                            DebugLog.Mod.printf("2x version of %s.pack not found.\n", string4);
                                                                                        }
                                                                                    }
                                                                                }

                                                                                mod0.addPack(string4, int1);
                                                                            } else if (string2.contains("tiledef=")) {
                                                                                String[] string8 = string2.replace("tiledef=", "").trim().split("\\s+");
                                                                                if (string8.length != 2) {
                                                                                    DebugLog.Mod.error("tiledef= line requires file name and file number");
                                                                                    object3 = null;
                                                                                    break label263;
                                                                                }

                                                                                String string9 = string8[0];

                                                                                try {
                                                                                    int5 = Integer.parseInt(string8[1]);
                                                                                } catch (NumberFormatException numberFormatException) {
                                                                                    DebugLog.Mod.error("tiledef= line requires file name and file number");
                                                                                    object2 = null;
                                                                                    break label262;
                                                                                }

                                                                                byte byte1 = 100;
                                                                                short short0 = 8190;
                                                                                short short1 = 16382;
                                                                                if (int5 < byte1 || int5 > short1) {
                                                                                    DebugLog.Mod
                                                                                        .error(
                                                                                            "tiledef=%s %d file number must be from %d to %d",
                                                                                            string9,
                                                                                            int5,
                                                                                            Integer.valueOf(byte1),
                                                                                            Integer.valueOf(short1)
                                                                                        );
                                                                                    object1 = null;
                                                                                    break label261;
                                                                                }

                                                                                mod0.addTileDef(string9, int5);
                                                                            } else if (string2.startsWith("versionMax=")) {
                                                                                String string10 = string2.replace("versionMax=", "").trim();
                                                                                if (!string10.isEmpty()) {
                                                                                    try {
                                                                                        mod0.versionMax = GameVersion.parse(string10);
                                                                                    } catch (Exception exception0) {
                                                                                        DebugLog.Mod.error("invalid versionMax: " + exception0.getMessage());
                                                                                        object0 = null;
                                                                                        break label260;
                                                                                    }
                                                                                }
                                                                            } else if (string2.startsWith("versionMin=")) {
                                                                                String string11 = string2.replace("versionMin=", "").trim();
                                                                                if (!string11.isEmpty()) {
                                                                                    try {
                                                                                        mod0.versionMin = GameVersion.parse(string11);
                                                                                    } catch (Exception exception1) {
                                                                                        DebugLog.Mod.error("invalid versionMin: " + exception1.getMessage());
                                                                                        object0 = null;
                                                                                        break label259;
                                                                                    }
                                                                                }
                                                                            }
                                                                        }

                                                                        mod0.bValid = true;
                                                                        mod1 = mod0;
                                                                    } catch (Throwable throwable0) {
                                                                        try {
                                                                            bufferedReader.close();
                                                                        } catch (Throwable throwable1) {
                                                                            throwable0.addSuppressed(throwable1);
                                                                        }

                                                                        throw throwable0;
                                                                    }

                                                                    bufferedReader.close();
                                                                    break label286;
                                                                }

                                                                bufferedReader.close();
                                                                break label287;
                                                            }

                                                            bufferedReader.close();
                                                            break label288;
                                                        }

                                                        bufferedReader.close();
                                                        break label289;
                                                    }

                                                    bufferedReader.close();
                                                    break label290;
                                                }

                                                bufferedReader.close();
                                                break label291;
                                            }

                                            bufferedReader.close();
                                        } catch (Throwable throwable2) {
                                            if (inputStreamReader != null) {
                                                try {
                                                    inputStreamReader.close();
                                                } catch (Throwable throwable3) {
                                                    throwable2.addSuppressed(throwable3);
                                                }
                                            }

                                            throw throwable2;
                                        }

                                        if (inputStreamReader != null) {
                                            inputStreamReader.close();
                                        }

                                        return (ChooseGameInfo.Mod)object3;
                                    }

                                    if (inputStreamReader != null) {
                                        inputStreamReader.close();
                                    }

                                    return (ChooseGameInfo.Mod)object3;
                                }

                                if (inputStreamReader != null) {
                                    inputStreamReader.close();
                                }

                                return (ChooseGameInfo.Mod)object2;
                            }

                            if (inputStreamReader != null) {
                                inputStreamReader.close();
                            }

                            return (ChooseGameInfo.Mod)object1;
                        }

                        if (inputStreamReader != null) {
                            inputStreamReader.close();
                        }

                        return (ChooseGameInfo.Mod)object0;
                    }

                    if (inputStreamReader != null) {
                        inputStreamReader.close();
                    }

                    return (ChooseGameInfo.Mod)object0;
                }

                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }

                return mod1;
            } catch (Exception exception2) {
                ExceptionLogger.logException(exception2);
            }
        }

        return null;
    }

    public static final class Map {
        private String dir;
        private Texture thumb;
        private String title;
        private ArrayList<String> lotsDir;
        private String desc;
        private boolean bFixed2x;

        public String getDirectory() {
            return this.dir;
        }

        public void setDirectory(String _dir) {
            this.dir = _dir;
        }

        public Texture getThumbnail() {
            return this.thumb;
        }

        public void setThumbnail(Texture _thumb) {
            this.thumb = _thumb;
        }

        public String getTitle() {
            return this.title;
        }

        public void setTitle(String _title) {
            this.title = _title;
        }

        public ArrayList<String> getLotDirectories() {
            return this.lotsDir;
        }

        public String getDescription() {
            return this.desc;
        }

        public void setDescription(String _desc) {
            this.desc = _desc;
        }

        public boolean isFixed2x() {
            return this.bFixed2x;
        }

        public void setFixed2x(boolean fixed) {
            this.bFixed2x = fixed;
        }
    }

    public static final class Mod {
        public String dir;
        public final File baseFile;
        public final File mediaFile;
        public final File actionGroupsFile;
        public final File animSetsFile;
        public final File animsXFile;
        private final ArrayList<String> posters = new ArrayList();
        public Texture tex;
        private ArrayList<String> require;
        private String name = "Unnamed Mod";
        private String desc = "";
        private String id;
        private String url;
        private String workshopID;
        private boolean bAvailableDone = false;
        private boolean available = true;
        private GameVersion versionMin;
        private GameVersion versionMax;
        private final ArrayList<ChooseGameInfo.PackFile> packs = new ArrayList();
        private final ArrayList<ChooseGameInfo.TileDef> tileDefs = new ArrayList();
        private boolean bRead = false;
        private boolean bValid = false;

        public Mod(String _dir) {
            this.dir = _dir;
            File file0 = new File(_dir).getAbsoluteFile();

            try {
                file0 = file0.getCanonicalFile();
            } catch (Exception exception) {
                ExceptionLogger.logException(exception);
            }

            this.baseFile = file0;
            this.mediaFile = new File(file0, "media");
            this.actionGroupsFile = new File(this.mediaFile, "actiongroups");
            this.animSetsFile = new File(this.mediaFile, "AnimSets");
            this.animsXFile = new File(this.mediaFile, "anims_X");
            File file1 = file0.getParentFile();
            if (file1 != null) {
                file1 = file1.getParentFile();
                if (file1 != null) {
                    this.workshopID = SteamWorkshop.instance.getIDFromItemInstallFolder(file1.getAbsolutePath());
                }
            }
        }

        public Texture getTexture() {
            if (this.tex == null) {
                String string = this.posters.isEmpty() ? null : (String)this.posters.get(0);
                if (!StringUtils.isNullOrWhitespace(string)) {
                    this.tex = Texture.getSharedTexture(string);
                }

                if (this.tex == null || this.tex.isFailure()) {
                    if (Core.bDebug && this.tex == null) {
                        DebugLog.Mod.println("failed to load poster " + (string == null ? this.id : string));
                    }

                    this.tex = Texture.getWhite();
                }
            }

            return this.tex;
        }

        public void setTexture(Texture _tex) {
            this.tex = _tex;
        }

        public int getPosterCount() {
            return this.posters.size();
        }

        public String getPoster(int index) {
            return index >= 0 && index < this.posters.size() ? (String)this.posters.get(index) : null;
        }

        public String getName() {
            return this.name;
        }

        public void setName(String _name) {
            this.name = _name;
        }

        public String getDir() {
            return this.dir;
        }

        public String getDescription() {
            return this.desc;
        }

        public ArrayList<String> getRequire() {
            return this.require;
        }

        public void setRequire(ArrayList<String> _require) {
            this.require = _require;
        }

        public String getId() {
            return this.id;
        }

        public void setId(String _id) {
            this.id = _id;
        }

        public boolean isAvailable() {
            if (this.bAvailableDone) {
                return this.available;
            } else {
                this.bAvailableDone = true;
                if (!this.isAvailableSelf()) {
                    this.available = false;
                    return false;
                } else {
                    ChooseGameInfo.tempStrings.clear();
                    ChooseGameInfo.tempStrings.add(this.getId());
                    if (!this.isAvailableRequired(ChooseGameInfo.tempStrings)) {
                        this.available = false;
                        return false;
                    } else {
                        this.available = true;
                        return true;
                    }
                }
            }
        }

        private boolean isAvailableSelf() {
            GameVersion gameVersion = Core.getInstance().getGameVersion();
            return this.versionMin != null && this.versionMin.isGreaterThan(gameVersion)
                ? false
                : this.versionMax == null || !this.versionMax.isLessThan(gameVersion);
        }

        private boolean isAvailableRequired(ArrayList<String> arrayList) {
            if (this.require != null && !this.require.isEmpty()) {
                for (int _int = 0; _int < this.require.size(); _int++) {
                    String string = ((String)this.require.get(_int)).trim();
                    if (!arrayList.contains(string)) {
                        arrayList.add(string);
                        ChooseGameInfo.Mod mod1 = ChooseGameInfo.getModDetails(string);
                        if (mod1 == null) {
                            return false;
                        }

                        if (!mod1.isAvailableSelf()) {
                            return false;
                        }

                        if (!mod1.isAvailableRequired(arrayList)) {
                            return false;
                        }
                    }
                }

                return true;
            } else {
                return true;
            }
        }

        @Deprecated
        public void setAvailable(boolean _available) {
        }

        public String getUrl() {
            return this.url == null ? "" : this.url;
        }

        public void setUrl(String _url) {
            if (_url.startsWith("http://theindiestone.com")
                || _url.startsWith("http://www.theindiestone.com")
                || _url.startsWith("http://pz-mods.net")
                || _url.startsWith("http://www.pz-mods.net")) {
                this.url = _url;
            }
        }

        public GameVersion getVersionMin() {
            return this.versionMin;
        }

        public GameVersion getVersionMax() {
            return this.versionMax;
        }

        public void addPack(String _name, int flags) {
            this.packs.add(new ChooseGameInfo.PackFile(_name, flags));
        }

        public void addTileDef(String _name, int fileNumber) {
            this.tileDefs.add(new ChooseGameInfo.TileDef(_name, fileNumber));
        }

        public ArrayList<ChooseGameInfo.PackFile> getPacks() {
            return this.packs;
        }

        public ArrayList<ChooseGameInfo.TileDef> getTileDefs() {
            return this.tileDefs;
        }

        public String getWorkshopID() {
            return this.workshopID;
        }
    }

    public static final class PackFile {
        public final String name;
        public final int flags;

        public PackFile(String _name, int _flags) {
            this.name = _name;
            this.flags = _flags;
        }
    }

    public static final class SpawnOrigin {
        public int x;
        public int y;
        public int w;
        public int h;

        public SpawnOrigin(int _x, int _y, int _w, int _h) {
            this.x = _x;
            this.y = _y;
            this.w = _w;
            this.h = _h;
        }
    }

    public static final class TileDef {
        public String name;
        public int fileNumber;

        public TileDef(String _name, int _fileNumber) {
            this.name = _name;
            this.fileNumber = _fileNumber;
        }
    }
}
